package main

import (
    "net/http"
    "io/ioutil"
    "encoding/base64"
    "encoding/json"
    "net/url"
    "strings"
    "fmt"
    //"sclog"
    //"bytes"
    //"log"
    "sclog"
)

var logger = &sclog.Logger{}

func main() {
    logger.Info("server start at localhost:8001")
    http.HandleFunc("/request", request)
    http.ListenAndServe(":8001", nil)
}

func request(w http.ResponseWriter, req *http.Request) {
    /*
    @param url: base64(url)
    @param header: base64(header)
    @param method: post
    @param postData: base64(postData)
     */

    logger.Info("Get a Request")
    req.ParseForm()

    var b64_pd, method, b64_header string
    b64_url := req.Form["url"][0]
    if req.Form["header"] != nil {
        b64_header = req.Form["header"][0]
    }

    if req.Form["postData"] != nil {
        b64_pd = req.Form["postData"][0]
    }

    if req.Form["method"] != nil {
        method = req.Form["method"][0]
    } else {
        method = "GET"
    }

    decode_url, _ := base64.StdEncoding.DecodeString(b64_url)
    decode_header, _ := base64.StdEncoding.DecodeString(b64_header)
    decode_pd, _ := base64.StdEncoding.DecodeString(b64_pd)

    target_url := string(decode_url)
    target_header := string(decode_header)
    target_pd := string(decode_pd)

    var h interface{}
    if target_header != "" {
        err := json.Unmarshal([]byte(target_header), &h)
        if err != nil {
            fmt.Println(err)
        }
    }

    var p interface{}
    data := url.Values{}
    if target_pd != "" {
        err := json.Unmarshal([]byte(target_pd), &p)
        if err != nil {
            fmt.Println(err)
        }

        for k, v := range p.(map[string]interface{}) {
            str, _ := v.(string)
            data.Set(k, str)
        }
    }
    form := strings.NewReader(data.Encode())
    strs := getHtml(target_url, h, method, form)
    ret := base64.StdEncoding.EncodeToString([]byte(strs))
    w.Write([]byte(ret))
}

func getHtml(url string, headers interface{}, method string, formData *strings.Reader) string {
    client := &http.Client{}
    req, _ := http.NewRequest(method, url, formData)
    if headers != nil {
        for k, v := range headers.(map[string]interface{}) {
            str, _ := v.(string)
            req.Header.Add(k, str)
        }
    }

    if method == "POST" {
        req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    }
    res, _ := client.Do(req)
    body, _ := ioutil.ReadAll(res.Body)
    bodyStr := string(body)

    res.Body.Close()
    return bodyStr
}

/*
test.py

import json
import requests
import base64

req = requests.Session()
headers = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*\/*;q=0.8',
    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36'
}

url = 'http://localhost:8001/request?url=%s&header=%s&method=%s&formData=%s'
target_url = base64.b64encode('http://www.baidu.com')
header = base64.b64encode(json.dumps(headers))

# get
res = req.get(url%(target_url, header, "GET",""))


# post
form_data = {"type":"1", "page": "2"}
fd = base64.b64encode(json.dumps(form_data))
res = req.get(url % (target_url, header, "POST", fd))

print base64.b64encode(res.content)
 */